﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Mozlite.Data;

namespace Mozlite.Components
{
    /// <summary>
    /// 配置基类。
    /// </summary>
    /// <typeparam name="TConfiguration">配置类型。</typeparam>
    [Serializable]
    public abstract class BaseConfiguration<TConfiguration> : IConfiguration
        where TConfiguration : BaseConfiguration<TConfiguration>, new()
    {
        /// <summary>
        /// 初始化类<see cref="BaseConfiguration"/>。
        /// </summary>
        public BaseConfiguration()
        {
            CreateDate = DateTime.Now;
        }

        /// <summary>
        /// 创建日期。
        /// </summary>
        [XmlIgnore]
        public DateTime CreateDate { get; set; }

        /// <summary>
        /// 最后更新日期。
        /// </summary>
        [XmlIgnore]
        public DateTime LastUpdateDate { get; set; }

        /// <summary>
        /// 获取缓存键。
        /// </summary>
        /// <returns>返回缓存键。</returns>
        protected virtual string GetCacheKey() {
            return "Configurations[{0}]".FormatWith(ConfigurationKey);
        }

        /// <summary>
        /// 获取配置唯一键。
        /// </summary>
        protected static string ConfigurationKey {
            get {
               return typeof(TConfiguration).GetFullName();
            }
        }

        /// <summary>
        /// 从数据库中加载配置。
        /// </summary>
        /// <param name="configuration">加载的配置实例对象。</param>
        public virtual void LoadConfiguration(ref TConfiguration configuration)
        {
            using (var reader = Database.ExecuteReader("SELECT * FROM moz_configurations WHERE [Key] = @Key", new { Key = ConfigurationKey }))
            {
                if (reader.Read())
                {
                    configuration = Cores.Deserialize<TConfiguration>(reader.GetString("SettingsXML"));
                    configuration.CreateDate = reader.GetDateTime("CreateDate");
                    configuration.LastUpdateDate = reader.GetDateTime("LastUpdateDate");
                }
                reader.Close();
            }
        }

        /// <summary>
        /// 获取当前配置。
        /// </summary>
        public static TConfiguration Current {
            get {
                var configuration = new TConfiguration();
                var key = configuration.GetCacheKey();
                return Caches.Get<TConfiguration>(key, () => {
                    configuration.LoadConfiguration(ref configuration);
                    Caches.Max(key, configuration);
                    return configuration;
                });
            }
        }

        /// <summary>
        /// 保存当前配置。
        /// </summary>
        /// <returns>返回保存结果。</returns>
        public virtual bool Save()
        {
            if (Database.ExecuteNonQuery(@"
IF EXISTS(SELECT 1 FROM moz_configurations WHERE [Key] = @Key) BEGIN
    UPDATE moz_configurations SET [SettingsXML] = @SettingsXML, [LastUpdateDate] = GETDATE() WHERE [Key] = @Key;
END ELSE BEGIN
    INSERT INTO moz_configurations([Key], [CreateDate], [LastUpdateDate], [SettingsXML])VALUES(@Key, GETDATE(), GETDATE(), @SettingsXML);
END", new { SettingsXML = Cores.Serialize((TConfiguration)this), Key = ConfigurationKey }))
            {
                Caches.Remove(this.GetCacheKey());
                return true;
            }
            return false;
        }
    }
}
